package org.origin.centre.support.utils;

import org.origin.centre.support.base.interfaces.XEnum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 枚举工具类
 *
 * @author ferret
 * @version 2024-05-08
 */
@SuppressWarnings({"unused", "unchecked"})
public final class EnumUtil {

    /**
     * 根据枚举类和代码获取标题
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param code 代码
     * @return 对应的标题，如果未找到则返回null
     */
    public static <T, E extends Enum<E>> String getTitle(Class<E> enumClass, T code) {
        if (code == null) {
            return null;
        }
        final E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e instanceof XEnum) {
                XEnum<T> xEnum = (XEnum<T>) e;
                if (xEnum.isEqual(code)) {
                    return xEnum.getTitle();
                }
            }
        }
        return null;
    }

    /**
     * 根据枚举类和另一个XEnum对象获取标题
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param other 另一个XEnum对象
     * @return 对应的标题，如果未找到则返回null
     */
    public static <T, E extends Enum<E>> String getTitle(Class<E> enumClass, XEnum<T> other) {
        if (other == null) {
            return null;
        }
        final E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e instanceof XEnum) {
                XEnum<T> xEnum = (XEnum<T>) e;
                if (xEnum.isEqual(other)) {
                    return xEnum.getTitle();
                }
            }
        }
        return null;
    }

    /**
     * 根据枚举类和多个代码获取标题列表
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param codes 多个代码
     * @return 对应的标题列表，如果未找到则返回null
     */
    public static <T, E extends Enum<E>> List<String> getTitles(Class<E> enumClass, T... codes) {
        if (codes == null || codes.length == 0) {
            return null;
        }
        List<String> result = new ArrayList<>();
        Map<String, String> titleMap = getTitleMap(enumClass);
        for (T code : codes) {
            if (code != null) {
                String title = titleMap.get(code.toString());
                if (BasicUtil.isNotBlank(title)) {
                    result.add(title);
                }
            }
        }
        return result;
    }

    /**
     * 根据枚举类和多个代码获取标题字符串，以逗号分隔
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param codes 多个代码
     * @return 对应的标题字符串，如果未找到则返回null
     */
    public static <T, E extends Enum<E>> String getTitlesString(Class<E> enumClass, T... codes) {
        if (codes == null || codes.length == 0) {
            return null;
        }
        StringBuilder result = new StringBuilder();
        Map<String, String> titleMap = getTitleMap(enumClass);
        for (T code : codes) {
            if (code != null) {
                String title = titleMap.get(code.toString());
                if (BasicUtil.isNotBlank(title)) {
                    if (result.length() > 0) {
                        result.append(",");
                    }
                    result.append(title);
                }
            }
        }
        return result.toString();
    }

    /**
     * 根据枚举类和多个XEnum对象获取标题列表
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param others 多个XEnum对象
     * @return 对应的标题列表，如果未找到则返回null
     */
    public static <T, E extends Enum<E>> List<String> getTitles(Class<E> enumClass, XEnum<T>... others) {
        if (others == null || others.length == 0) {
            return null;
        }
        List<String> result = new ArrayList<>();
        Map<String, String> titleMap = getTitleMap(enumClass);
        for (XEnum<T> other : others) {
            if (other != null && other.getCode() != null) {
                String title = titleMap.get(other.getCode().toString());
                if (BasicUtil.isNotBlank(title)) {
                    result.add(title);
                }
            }
        }
        return result;
    }

    /**
     * 根据枚举类和多个XEnum对象获取标题字符串，以逗号分隔
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param others 多个XEnum对象
     * @return 对应的标题字符串，如果未找到则返回null
     */
    public static <T, E extends Enum<E>> String getTitlesString(Class<E> enumClass, XEnum<T>... others) {
        if (others == null || others.length == 0) {
            return null;
        }
        StringBuilder result = new StringBuilder();
        Map<String, String> titleMap = getTitleMap(enumClass);
        for (XEnum<T> other : others) {
            if (other != null && other.getCode() != null) {
                String title = titleMap.get(other.getCode().toString());
                if (BasicUtil.isNotBlank(title)) {
                    if (result.length() > 0) {
                        result.append(",");
                    }
                    result.append(title);
                }
            }
        }
        return result.toString();
    }

    /**
     * 获取枚举类的所有标题映射
     *
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @return 标题映射，键为代码的字符串形式，值为标题
     */
    public static <E extends Enum<E>> Map<String, String> getTitleMap(Class<E> enumClass) {
        Map<String, String> result = new HashMap<>();
        final E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e instanceof XEnum<?> xEnum) {
                if (xEnum.getCode() != null) {
                    result.put(xEnum.getCode().toString(), xEnum.getTitle());
                }
            }
        }
        return result;
    }

    /**
     * 获取枚举类的所有XEnum对象映射
     *
     * @param <T> 代码类型
     * @param <E> 枚举类型
     * @param enumClass 枚举类
     * @param cls 代码类型类
     * @return XEnum对象映射，键为代码的字符串形式，值为XEnum对象
     */
    public static <T, E extends Enum<E>> Map<String, XEnum<T>> getXEnumMap(Class<E> enumClass, Class<T> cls) {
        Map<String, XEnum<T>> result = new HashMap<>();
        final E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e instanceof XEnum) {
                XEnum<T> xEnum = (XEnum<T>) e;
                if (xEnum.getCode() != null) {
                    result.put(xEnum.getCode().toString(), xEnum);
                }
            }
        }
        return result;
    }

    /**
     * 根据枚举类和名称获取枚举对象
     *
     * @param <T> 枚举类型
     * @param clazz 枚举类
     * @param name 名称
     * @return 对应的枚举对象
     */
    public static <T extends Enum<T>> T getEnum(Class<T> clazz, String name) {
        return Enum.valueOf(clazz, name);
    }

}

